package com.opennews.openplatform.familyexpenseapi.controller

import com.opennews.openplatform.familyexpenseapi.common.constant.IncomeExpenseType
import com.opennews.openplatform.familyexpenseapi.dto.income.expense.detail.type.*
import com.opennews.openplatform.familyexpenseapi.service.IncomeExpenseDetailTypeService
import com.opennews.openplatform.myspringbootcore.dto.ApiResponse
import com.opennews.openplatform.myspringbootcore.util.getSuccessResponse
import com.opennews.openplatform.myspringbootmvccore.security.RequestIdentityExtractor
import jakarta.validation.Valid
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/income-expense-detail-type")
class IncomeExpenseDetailTypeController(
    private val incomeExpenseDetailTypeService: IncomeExpenseDetailTypeService,
    private val requestIdentityExtractor: RequestIdentityExtractor,
) {
    @GetMapping("/query-by-account-group")
    fun queryByAccountGroup(@RequestParam incomeExpenseType: String): ResponseEntity<ApiResponse<List<Map<String, Any>>>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = incomeExpenseDetailTypeService.queryByAccountGroup(accountGroupId, incomeExpenseType)

        return getSuccessResponse(result)
    }

    @GetMapping("/check-existing")
    fun checkExisting(
        @RequestParam incomeExpenseType: String,
        @RequestParam id: String,
        @RequestParam name: String,
    ): ResponseEntity<ApiResponse<Boolean>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = incomeExpenseDetailTypeService.checkExisting(accountGroupId, incomeExpenseType, id, name)

        return getSuccessResponse(result)
    }

    @GetMapping("/query-analysis-not-included-detail-types")
    fun queryAnalysisNotIncludedDetailTypes(): ResponseEntity<ApiResponse<Map<String, Any>>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()

        val incomeDetailTypes = incomeExpenseDetailTypeService.queryAnalysisNotIncludedDetailTypes(
            accountGroupId,
            IncomeExpenseType.INCOME,
        )

        val expenseDetailTypes = incomeExpenseDetailTypeService.queryAnalysisNotIncludedDetailTypes(
            accountGroupId,
            IncomeExpenseType.EXPENSE,
        )

        return getSuccessResponse(
            mapOf(
                "incomeDetailTypes" to incomeDetailTypes,
                "expenseDetailTypes" to expenseDetailTypes,
            )
        )
    }

    @PostMapping("/reset-order")
    fun resetOrder(@Valid @RequestBody data: ResetOrderIncomeExpenseDetailTypeDto): ResponseEntity<ApiResponse<Any?>> {
        val detailTypeIds = data.detailTypeIds
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        incomeExpenseDetailTypeService.resetOrder(accountGroupId, detailTypeIds)

        return getSuccessResponse()
    }

    @PostMapping("/add")
    fun add(@Valid @RequestBody data: CreateIncomeExpenseDetailTypeDto): ResponseEntity<ApiResponse<Map<String, Any>?>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = incomeExpenseDetailTypeService.add(data, accountGroupId)

        return getSuccessResponse(result)
    }

    @PostMapping("/update")
    fun update(@Valid @RequestBody data: UpdateIncomeExpenseDetailTypeDto): ResponseEntity<ApiResponse<Map<String, Any>?>> {
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = incomeExpenseDetailTypeService.update(data, accountGroupId)

        return getSuccessResponse(result)
    }

    @PostMapping("/delete")
    fun delete(@Valid @RequestBody data: IncomeExpenseDetailTypeWithNameDto): ResponseEntity<ApiResponse<Boolean>> {
        val incomeExpenseType = data.incomeExpenseType
        val name = data.name
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = incomeExpenseDetailTypeService.delete(incomeExpenseType, name, accountGroupId)

        return getSuccessResponse(result)
    }

    @PostMapping("/batch-delete")
    fun batchDelete(@Valid @RequestBody data: IncomeExpenseDetailTypeWithNamesDto): ResponseEntity<ApiResponse<List<String>>> {
        val incomeExpenseType = data.incomeExpenseType
        val names = data.names
        val accountGroupId = requestIdentityExtractor.getClaims().accountGroupId.asString()
        val result = incomeExpenseDetailTypeService.delete(incomeExpenseType, names, accountGroupId)

        return getSuccessResponse(result)
    }
}